home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / demobook / bookmove.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  45.8 KB  |  1,775 lines

  1. /*
  2.  * Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /***************************************************************************
  18. /* bookmove.c
  19. /* this file contains routines to open and turn the pages of the demobook 
  20. /*
  21. /* need to:
  22. /*    1) add cool binding to book
  23. /*    2) pre-calculate lighting arrays
  24. /*    3) integrate frame-by-frame rotation
  25. /*    4) use color-map ramps on LIGHT (starter) graphics instead of 
  26. /*       switching back and forth between single and double buffer
  27. /*
  28. /*    David Ligon
  29. ****************************************************************************/
  30.  
  31. #include <math.h>
  32. #include <stdio.h>
  33. #include <gl.h>
  34. #include <get.h>
  35. #include "exglobals.h"
  36. #include "bookmove.h"
  37. #include "bookgfx.h"
  38. #include "exbookglo.h"
  39.  
  40. #define DBUG FALSE
  41. #define LIGHTCALC FALSE
  42. #define DRAWSOLIDPAGES FALSE
  43.  
  44. void mknorms();
  45. static float getangle(register float vtx1[3], register float vtx2[3]);
  46. void mkangles(void);
  47. void dographics(float vtx[3], float angle);
  48. void drawicons(struct pagestruct *thispage, int side, float position[PGSEGS][VPGSEGS][3], float rot_angle[PGSEGS-1]);
  49.  
  50. float ropenangle[OPENFRAMES][PGSEGS -1];
  51. float lopenangle[OPENFRAMES][PGSEGS -1];
  52. float backrturnangle[TURNFRAMES][PGSEGS -1];
  53. float frontrturnangle[TURNFRAMES][PGSEGS -1];
  54. float backlturnangle[TURNFRAMES][PGSEGS -1];
  55. float frontlturnangle[TURNFRAMES][PGSEGS -1];
  56.  
  57.  
  58. void mk_open_arrays(void);
  59. void mk_turn_arrays(void);
  60. void openbook(register int rotateflag);
  61. void drawopenframe(register int pgn);
  62. void pickdrawopenframe(register int pgn);
  63. void turnpage(int side);
  64. void rtol_turn(void);
  65. void ltor_turn(void);
  66. void mksinglebuffer(void);
  67. void mkdoublebuffer(void);
  68. int isdoublebuffer(void);
  69. void drawbinding(void);
  70.  
  71. void pickdrawedges(register float ropg[PGSEGS][VPGSEGS][THREED],
  72.     register float lopg[PGSEGS][VPGSEGS][THREED],
  73.     register float robase[3][2][THREED], register float lobase[3][2][THREED]);
  74. static void drawopencover(float rcover[COVERSEGS][2][THREED], 
  75.     float lcover[PGSEGS][2][THREED]);
  76. static void fillopenpages(float ropg[PGSEGS][VPGSEGS][THREED], 
  77.     float lopg[PGSEGS][VPGSEGS][THREED], float robase[3][2][THREED], 
  78.     float lobase[3][2][THREED]);
  79. static void drawopenpages(float rpg[PGSEGS][VPGSEGS][THREED], 
  80.     float lpg[PGSEGS][VPGSEGS][THREED]);
  81. static void drawsquare(float pgarray[PGSEGS][VPGSEGS][THREED], int x, int y);
  82. static void drawoutlinesquare(float pgarray[PGSEGS][VPGSEGS][THREED], int x, int y);
  83. void setcovercolor(struct grptmpltstruct *grpptr);
  84. static void mkcolor(float carray[3], float srcarray[3], float coord[3]);
  85. static void drawcrack();
  86. static void mk_right_basepg(void);
  87.  
  88. #if DRAWSOLIDPAGES
  89. static void drawsolidpages(void);
  90. #endif
  91.  
  92. #if LIGHTCALC
  93. static void printcolor(float carray[3]);
  94. #endif
  95.  
  96.  
  97. /*******************************************************
  98. /* BUFFER STUFF
  99. /******************************************************/
  100.  
  101. /* return TRUE is drawmode is double buffer */
  102. int isdoublebuffer()
  103. {
  104.     register int isdouble;
  105.  
  106.     isdouble = getdisplaymode();
  107.     
  108.     if (isdouble == DMDOUBLE || isdouble == DMRGBDOUBLE)
  109.     return(TRUE);
  110.     else
  111.     return(FALSE);
  112. }
  113.  
  114.  
  115. /* return TRUE if is eight bitplane machine */
  116. int iseightbit()
  117. {
  118.     if (getgdesc(GD_BITS_NORM_SNG_RED) +
  119.     getgdesc(GD_BITS_NORM_SNG_GREEN) +
  120.     getgdesc(GD_BITS_NORM_SNG_BLUE) == 8) {
  121.         return(TRUE);
  122.     } else {
  123.     return(FALSE);
  124.     }
  125. }
  126.  
  127.  
  128. /* clear back buffer and make single buffer for static page */
  129. void mksinglebuffer()
  130. {
  131.     if (isdoublebuffer() && iseightbit()) {
  132.     /* clear back buffer so old image won't show */
  133.     /* frontbuffer(TRUE); */
  134.     cpack(0);
  135.     clear();
  136.     singlebuffer();
  137. /*    gconfig(); */
  138.     }
  139. }
  140.  
  141.  
  142. /* make doublebuffer for movement */
  143. void mkdoublebuffer()
  144. {
  145.     if (!isdoublebuffer() && iseightbit()) {
  146.     /* either get funky colors or blank screen-funky colors look better */
  147.     cpack(0);
  148.     clear();
  149.     doublebuffer();
  150. /*    gconfig(); */
  151.     }
  152. }
  153.  
  154.  
  155. /*******************************************************
  156. /* ICON STUFF
  157. /******************************************************/
  158.  
  159. void unhighlighticon()
  160. {
  161.    dooverlayview();
  162.    color(PUP_CLEAR);
  163.    clear();
  164. }
  165.  
  166. void highlightsquare(int sideflag, register int x, register int y)
  167. {
  168.    if (x >= 0 && y >= 0)
  169.       {
  170.       unhighlighticon();
  171.    color(PUP_COLOR);
  172.    pushmatrix();
  173.    rot(-25.0, 'x');
  174.    translate(0.0, 1.0, 0.0);
  175.    if (sideflag == 0)  /* leftside */
  176.       drawoutlinesquare(lopenpg[0], x, y);
  177.    else  /* right side */
  178.       drawoutlinesquare(ropenpg[0], x, y);
  179.    popmatrix();
  180.    dobookview();
  181.       }
  182. }
  183.  
  184. void highlighticon(pk, thispage, side)
  185. int pk;
  186. struct pagestruct *thispage;
  187. int side;
  188. {
  189.    int j, k, limit;
  190.    struct polylist *curpoly;
  191.    float angle;
  192.    struct icntmpltstruct *curicon;
  193.    struct iconstruct *tmpiconptr;
  194.    int i, numicons;
  195.  
  196.    if (side == 0)
  197.       {
  198.       tmpiconptr = thispage -> backicons;
  199.       numicons = thispage->backnumicons;
  200.       if (numicons > 21)
  201.          numicons = 20;
  202.       }
  203.    else if (side == 1)
  204.       {
  205.       tmpiconptr = thispage ->fronticons;
  206.       numicons = thispage->frontnumicons;
  207.       if (numicons > 21)
  208.          numicons = 20;
  209.       }
  210.    if (tmpiconptr != NULL && pk <= numicons)
  211.       {
  212.       i = 0;
  213.       while (i < pk)
  214.          {
  215.          if (!Hide || tmpiconptr->ok)
  216.             i++;
  217.          tmpiconptr = tmpiconptr->nexticon;
  218.          }
  219.  
  220.       unhighlighticon();
  221.       color(PUP_COLOR);
  222.       pushmatrix();
  223.       rot(-25.0, 'x');
  224.       translate(0.0, 1.0, 0.0);
  225.       if (side == 1) /* right page */
  226.          drawoutlinesquare(ropenpg[0], (int)(tmpiconptr->xposition_ndx), (int)(tmpiconptr->yposition_ndx));
  227.       else if (side == 0)  /* left page */
  228.          drawoutlinesquare(lopenpg[0], (int)(tmpiconptr->xposition_ndx), (int)(tmpiconptr->yposition_ndx));
  229.       popmatrix();
  230.       dobookview();
  231.       }
  232. }
  233.  
  234. void pickdrawicons(struct pagestruct *thispage, int side, float position[PGSEGS][VPGSEGS][3], float rot_angle[PGSEGS-1])
  235. {
  236.     register long cursm;
  237.     register short x, y;
  238.     struct iconstruct *tmpiconptr;
  239.     int i;
  240.  
  241.     if (side == FRONT)
  242.        tmpiconptr = thispage->fronticons;
  243.     else
  244.        tmpiconptr = thispage->backicons;
  245.  
  246.     i = 0;
  247.     while (i < ICONLIMIT && tmpiconptr != NULL)
  248.        {
  249.        if (!Hide || tmpiconptr->ok)
  250.           {
  251.           pushmatrix();
  252.           if (side == BACK)
  253.              loadname(-i-1);
  254.           else
  255.              loadname(i);
  256.           x = tmpiconptr->xposition_ndx;
  257.           y = tmpiconptr->yposition_ndx;
  258.           drawsquare(position, x, y);
  259.           popmatrix();
  260.           i++;
  261.           }
  262.        tmpiconptr = tmpiconptr->nexticon;
  263.        }
  264. }
  265.  
  266. void drawicons(struct pagestruct *thispage, int side, float position[PGSEGS][VPGSEGS][3], float rot_angle[PGSEGS-1])
  267. {
  268.     register long cursm;
  269.     register short x, y;
  270.     struct iconstruct *tmpiconptr;
  271.     int i;
  272.     float transname;
  273.  
  274.     cursm = getsm();
  275.     shademodel(FLAT);
  276.  
  277.     if (side == FRONT)
  278.        tmpiconptr = thispage->fronticons;
  279.     else
  280.        tmpiconptr = thispage->backicons;
  281.  
  282.     i = 0;
  283.     while (i < ICONLIMIT && tmpiconptr != NULL)
  284.        {
  285.        if (!Hide || tmpiconptr->ok)
  286.           {
  287.        transname = -.15;
  288.        pushmatrix();
  289.        x = tmpiconptr->xposition_ndx;
  290.        y = tmpiconptr->yposition_ndx;
  291.           if (i == selected && thispage == selectedpage)
  292.              {
  293.              c3s(morecolors[11]);
  294.              if (side == FRONT)
  295.                 drawoutlinesquare(ropenpg[0], x, y);
  296.              else
  297.                 drawoutlinesquare(lopenpg[0], x, y);
  298.              }
  299.        if (side == FRONT)
  300.           {
  301.           translate(position[x][y][0], position[x][y][1]+.4, position[x][y][2]);
  302.           rotate( (int)(rot_angle[x] * 10 + 0.5), 'y'); 
  303.           }
  304.        else
  305.           {
  306.           translate(position[x+1][y][0], position[x+1][y][1]+.4, position[x+1][y][2]);
  307.           rotate( (int)(rot_angle[x] * 10 + 0.5), 'y'); 
  308.           }
  309.        if (tmpiconptr->iconptr->poly != NULL)
  310.           drawicon_geom(0, tmpiconptr->iconptr);
  311.        else if (tmpiconptr->iconptr->tex_image != NULL)
  312.           drawicon_img(0,tmpiconptr->iconptr);
  313.        else
  314.           transname = 1.125;
  315.        pushmatrix();
  316.        translate(0.0, transname, 0.0);
  317.        draw_demoname(tmpiconptr->iconptr);
  318.        popmatrix();
  319.        popmatrix();
  320.        i++;
  321.           }  /* end if tmpiconptr->ok */
  322.        tmpiconptr = tmpiconptr->nexticon;
  323.        }
  324.  
  325.     shademodel(cursm);
  326. }
  327.  
  328. void drawselectedicon( struct pagestruct *thispage, int iconnum)
  329. {
  330.    short x, y;
  331.    struct iconstruct *tmpiconptr;
  332.    int i;
  333.  
  334.    if (thispage != NULL)
  335.       {
  336.       if (thispage == leftpage)
  337.          tmpiconptr = thispage->backicons;
  338.       else if (thispage == rightpage)
  339.          tmpiconptr = thispage->fronticons;
  340.       i = 0;
  341.       while (tmpiconptr != NULL && (i != iconnum || (!tmpiconptr->ok && Hide)))
  342.          {
  343.          if (!Hide || tmpiconptr->ok)
  344.             i++;
  345.          tmpiconptr = tmpiconptr->nexticon;
  346.          }
  347.  
  348.       if (tmpiconptr != NULL)
  349.          {
  350.       
  351.          x = tmpiconptr->xposition_ndx;
  352.          y = tmpiconptr->yposition_ndx;
  353.    
  354.          pushmatrix();
  355.          rot(-25.0, 'x');
  356.          translate(0.0, 1.0, 0.0);
  357.          frontbuffer(TRUE);
  358. /*
  359.       if (thispage == leftpage)
  360.          {
  361.          drawsquare(lopenpg[0], x, y);
  362.          pushmatrix();
  363.          translate( lopenpg[0][x][y][0], lopenpg[0][x][y][1]+.4, lopenpg[0][x][y][2]);
  364.          rotate( (int)(lopenangle[0][x] * 10 + 0.5), 'y'); 
  365.          }
  366.       else if (thispage == rightpage)
  367.          {
  368.          drawsquare(ropenpg[0], x, y);
  369.          pushmatrix();
  370.          translate(ropenpg[0][x][y][0], ropenpg[0][x][y][1]+.4, ropenpg[0][x][y][2]);
  371.          rotate( (int)(ropenangle[0][x] * 10 + 0.5), 'y');
  372.          }
  373.       if (tmpiconptr->iconptr->poly != NULL)
  374.          drawicon_geom(0, tmpiconptr->iconptr);
  375.       else if (tmpiconptr->iconptr->tex_image != NULL)
  376.          drawicon_img(0,tmpiconptr->iconptr);
  377.       pushmatrix();
  378.       translate(0.0, .2, 0.0);
  379.       draw_demoname(tmpiconptr->iconptr);
  380.       popmatrix();
  381.       popmatrix();
  382. */
  383.          if (thispage == leftpage)
  384.             {
  385.             c3s(morecolors[11]);
  386.             drawoutlinesquare(lopenpg[0], x, y);
  387.             }
  388.          else if (thispage == rightpage)
  389.             {
  390.             c3s(morecolors[11]);
  391.             drawoutlinesquare(ropenpg[0], x, y);
  392.             }
  393.  
  394.          frontbuffer(FALSE);
  395.          popmatrix();
  396.          }
  397.       }
  398. }
  399.  
  400. void undrawselectedicon( struct pagestruct *thispage, int iconnum)
  401. {
  402.    short x, y;
  403.    struct iconstruct *tmpiconptr;
  404.    int i;
  405.    float transname;
  406.  
  407.    if (thispage != NULL)
  408.       {
  409.    if (thispage == leftpage)
  410.       tmpiconptr = thispage->backicons;
  411.    else if (thispage == rightpage)
  412.       tmpiconptr = thispage->fronticons;
  413.    i = 0;
  414.    while (tmpiconptr != NULL && (i != iconnum || (!tmpiconptr->ok && Hide)))
  415.       {
  416.       if (!Hide || tmpiconptr->ok)
  417.          i++;
  418.       tmpiconptr = tmpiconptr->nexticon;
  419.       }
  420.  
  421.    if (tmpiconptr != NULL)
  422.       {
  423.    x = tmpiconptr->xposition_ndx;
  424.    y = tmpiconptr->yposition_ndx;
  425.    transname = -.15;
  426.  
  427.    pushmatrix();
  428.    rot(-25.0, 'x');
  429.    translate(0.0, 1.0, 0.0);
  430.    frontbuffer(TRUE);
  431.    if (thispage == leftpage)
  432.       {
  433.       drawsquare(lopenpg[0], x, y);
  434.       pushmatrix();
  435.       translate( lopenpg[0][x+1][y][0], lopenpg[0][x+1][y][1]+.4,
  436.                       lopenpg[0][x+1][y][2]);
  437.       rotate( (int)(lopenangle[0][x] * 10 + 0.5), 'y'); 
  438.       }
  439.    else if (thispage == rightpage)
  440.       {
  441.       drawsquare(ropenpg[0], x, y);
  442.       pushmatrix();
  443.       translate(ropenpg[0][x][y][0],ropenpg[0][x][y][1]+.4, ropenpg[0][x][y][2]);
  444.       rotate( (int)(ropenangle[0][x] * 10 + 0.5), 'y'); 
  445.       }
  446.    if (tmpiconptr->iconptr->poly != NULL)
  447.       drawicon_geom(0, tmpiconptr->iconptr);
  448.    else if (tmpiconptr->iconptr->tex_image != NULL)
  449.       drawicon_img(0,tmpiconptr->iconptr);
  450.    else
  451.       transname = 1.125;
  452.    pushmatrix();
  453.    translate(0.0, transname, 0.0);
  454.    draw_demoname(tmpiconptr->iconptr);
  455.    popmatrix();
  456.    popmatrix();
  457.  
  458.    frontbuffer(FALSE);
  459.    popmatrix();
  460.       }
  461.       }
  462. }
  463.  
  464. void dographics(float vtx[3], float angle)
  465. {
  466.     register int i;
  467.  
  468.     static float sqr[4][3] = {{0.3,0.6,0.0},{1.7,0.6,0.0},{1.7,1.7,0.0},
  469.                   {0.3,1.7,0.0}};
  470.     static float tri[3][3] = {{0.6,0.2,0.0},{1.8,0.7,0.0},{1.0,1.2,0.0}};
  471.     float sqcolor[3];
  472.     float tricolor[3];
  473.  
  474.     sqcolor[0] = sqcolor[1] = 0.0; sqcolor[2] = 1.0;
  475.     tricolor[0] = 0.0; tricolor[1] = 0.5; tricolor[2] = 1.0;
  476.  
  477.     pushmatrix();
  478.     translate(vtx[0],vtx[1],vtx[2]);
  479.     rotate((int)(angle * 10 + 0.5),'y');
  480.  
  481.     for (i = 1; i < 6; i++) {
  482.     pushmatrix();
  483.     scale(1.0/(float)i,1.0/(float)i,1.0);
  484.  
  485.     c3f(sqcolor);
  486.     bgnpolygon();
  487.         v3f(sqr[0]);
  488.         v3f(sqr[1]);
  489.         v3f(sqr[2]);
  490.         v3f(sqr[3]);
  491.     endpolygon();
  492.  
  493.     cpack(0);
  494.     bgnclosedline();
  495.         v3f(sqr[0]);
  496.         v3f(sqr[1]);
  497.         v3f(sqr[2]);
  498.         v3f(sqr[3]);
  499.     endclosedline();
  500.     popmatrix();
  501.     }
  502.  
  503.     for(i = 1; i < 6; i++) {
  504.     pushmatrix();
  505.     scale(1.0/(float)i,1.0/(float)i,1.0);
  506.     c3f(tricolor);
  507.     bgnpolygon();
  508.         v3f(tri[0]);
  509.         v3f(tri[1]);
  510.         v3f(tri[2]);
  511.     endpolygon();
  512.  
  513.     cpack(0);
  514.     bgnclosedline();
  515.         v3f(tri[0]);
  516.         v3f(tri[1]);
  517.         v3f(tri[2]);
  518.     endclosedline();
  519.     popmatrix();
  520.     }
  521.     popmatrix();
  522. }    
  523.  
  524.  
  525. /*******************************************************
  526. /* INIT STUFF
  527. /******************************************************/
  528.  
  529. /* make arrays for opening the book */
  530. void mk_open_arrays()
  531. {
  532.     register int pgn, x, y;
  533.  
  534.     /* make the array for the right pages opening the book */
  535.      for (pgn = 0; pgn < OPENFRAMES; pgn++) {
  536.     for (x = 0;x < PGSEGS; x++) {
  537.         for(y = 0; y < VPGSEGS; y++) {
  538.         ropenpg[pgn][x][y][0] = openpg[pgn][x][0] * SCALE;
  539.         ropenpg[pgn][x][y][1] = PGHT/(VPGSEGS - 1) * y;
  540.         ropenpg[pgn][x][y][2] = openpg[pgn][x][1] * SCALE;
  541.         }
  542.     }
  543.     }
  544.  
  545.     /* make the array for the left pages opening the book */
  546.     for (pgn = 0; pgn < OPENFRAMES; pgn++) {
  547.     for (x = 0;x < PGSEGS; x++) {
  548.         for (y = 0; y < VPGSEGS; y++) {
  549.         lopenpg[pgn][x][y][0] = ropenpg[pgn][x][y][0] * -1.0;
  550.         lopenpg[pgn][x][y][1] = ropenpg[pgn][x][y][1];
  551.         lopenpg[pgn][x][y][2] = ropenpg[pgn][x][y][2];
  552.         }
  553.     }
  554.     } 
  555.  
  556.     /*  offset the crack .01" for zbuffer */
  557.     crackvtx[0][0] = ropenpg[0][0][0][0];
  558.     crackvtx[0][1] = ropenpg[0][0][0][1];
  559.     crackvtx[0][2] = ropenpg[0][0][0][2] + 0.0;
  560.     crackvtx[1][0] = ropenpg[0][0][VPGSEGS - 1][0];
  561.     crackvtx[1][1] = ropenpg[0][0][VPGSEGS - 1][1];
  562.     crackvtx[1][2] = ropenpg[0][0][VPGSEGS - 1][2] + 0.0;
  563.  
  564.     /* make the array for the right cover */
  565.     for (pgn = 0; pgn < OPENFRAMES; pgn++) {
  566.     for (x = 0;x < COVERSEGS; x++) {
  567.         ropencover[pgn][x][0][0] = opencover[pgn][x][0] * SCALE;
  568.         ropencover[pgn][x][0][1] = -COVEROVERHANG;
  569.         ropencover[pgn][x][0][2] = opencover[pgn][x][1] * SCALE;
  570.         ropencover[pgn][x][1][0] = opencover[pgn][x][0] * SCALE;
  571.         ropencover[pgn][x][1][1] = PGHT + COVEROVERHANG;
  572.         ropencover[pgn][x][1][2] = opencover[pgn][x][1] * SCALE;
  573.     }
  574.     }
  575.  
  576.     /* make the array for the left cover */
  577.     for (pgn = 0; pgn < OPENFRAMES; pgn++) {
  578.     for (x = 0;x < COVERSEGS; x++) {
  579.         for (y = 0; y < 2; y++) {
  580.         lopencover[pgn][x][y][0] = ropencover[pgn][x][y][0] * -1.0;
  581.         lopencover[pgn][x][y][1] = ropencover[pgn][x][y][1];
  582.         lopencover[pgn][x][y][2] = ropencover[pgn][x][y][2];
  583.         }
  584.     }
  585.     }
  586.  
  587.     /* make array for the binding */
  588.     for (x = 0; x < BINDINGSEGS; x++) {
  589.         sbinding[x][0][0] = binding[x][0] * SCALE;
  590.         sbinding[x][0][1] = -COVEROVERHANG;
  591.         sbinding[x][0][2] = binding[x][1] * SCALE;
  592.         sbinding[x][1][0] = binding[x][0] * SCALE;
  593.         sbinding[x][1][1] = PGHT + COVEROVERHANG;
  594.         sbinding[x][1][2] = binding[x][1] * SCALE;
  595.     }
  596.  
  597.     /* make array for the page next to the cover */
  598.     mk_right_basepg();
  599.  
  600.     for (pgn = 0; pgn < OPENFRAMES; pgn++) {
  601.     for (x = 0; x < 3; x++) {
  602.         for(y = 0; y < 2; y++) {
  603.         lopenbasepg[pgn][x][y][0] = ropenbasepg[pgn][x][y][0] * -1.0;
  604.         lopenbasepg[pgn][x][y][1] = ropenbasepg[pgn][x][y][1];
  605.         lopenbasepg[pgn][x][y][2] = ropenbasepg[pgn][x][y][2];
  606.         }
  607.     }
  608.     }
  609.  
  610.     mksqrttable();
  611. }
  612.  
  613.  
  614. /* assume cover is 10" and we want 1/4" cover overlap */
  615. static void mk_right_basepg()
  616. {
  617.     int pgn, x;
  618.     float tenx, tenz;
  619.  
  620.     for (pgn = 0; pgn < OPENFRAMES; pgn++) {
  621.     ropenbasepg[pgn][0][0][0] = 0.0;
  622.     ropenbasepg[pgn][0][0][1] = 0.0;
  623.  
  624.     /* gap between pages and binding increases from 1/6"" to 0.25" */
  625.     ropenbasepg[pgn][0][0][2] = 
  626.         -0.5 + ((float)(OPENFRAMES - 1 - pgn) / (OPENFRAMES -1) * 0.25);
  627.     ropenbasepg[pgn][1][0][0] = ropencover[pgn][0][0][0];
  628.     ropenbasepg[pgn][1][0][1] = 0.0;
  629.     ropenbasepg[pgn][1][0][2] = ropencover[pgn][0][0][2];
  630.     tenx = ropencover[pgn][COVERSEGS - 1][0][0] - ropencover[pgn][0][0][0];
  631.     tenz = ropencover[pgn][COVERSEGS - 1][0][2] - ropencover[pgn][0][0][2];
  632.     tenx = tenx / 43.0;
  633.     tenz = tenz / 43.0;
  634.     ropenbasepg[pgn][2][0][0] = ropencover[pgn][COVERSEGS-1][0][0] - tenx;
  635.     ropenbasepg[pgn][2][0][1] = 0.0;
  636.     ropenbasepg[pgn][2][0][2] = ropencover[pgn][COVERSEGS-1][0][2] - tenz;
  637.     }
  638.  
  639.     for (pgn = 0; pgn < OPENFRAMES; pgn++) {
  640.     for (x = 0; x < 3; x++) {
  641.         ropenbasepg[pgn][x][1][0] = ropenbasepg[pgn][x][0][0];
  642.         ropenbasepg[pgn][x][1][1] = PGHT;
  643.         ropenbasepg[pgn][x][1][2] = ropenbasepg[pgn][x][0][2];
  644.     }
  645.     }
  646. }
  647.  
  648.  
  649.  
  650. mksqrttable()
  651. {
  652.     register int i;
  653.  
  654.     for (i = 0; i < 4000; i++) {
  655.     sqrttable[i] = fsqrt((float)i);
  656.     }
  657.  
  658. }
  659.  
  660.  
  661. /* make additional arrays needed to turn pages */
  662. void mk_turn_arrays()
  663. {
  664.     register int pgn, x, y;
  665.  
  666.     for (pgn = 0; pgn < TURNFRAMES; pgn++) {
  667.     for(x = 0; x < PGSEGS; x++) {
  668.         for(y = 0; y < VPGSEGS; y++) {
  669.         rtolpglst[pgn][x][y][0] = turnpg[pgn][x][0] * SCALE;
  670.         rtolpglst[pgn][x][y][1] = PGHT/(VPGSEGS - 1) * y;
  671.         rtolpglst[pgn][x][y][2] = turnpg[pgn][x][1] * SCALE;
  672.         }
  673.     }
  674.     }
  675.     for (pgn = 0; pgn < TURNFRAMES; pgn++) {
  676.     for(x = 0; x < PGSEGS; x++) {
  677.         for(y = 0; y < VPGSEGS; y++) {
  678.         ltorpglst[pgn][x][y][0] = rtolpglst[pgn][x][y][0] * -1.0;
  679.         ltorpglst[pgn][x][y][1] = rtolpglst[pgn][x][y][1];
  680.         ltorpglst[pgn][x][y][2] = rtolpglst[pgn][x][y][2];
  681.         }
  682.     }
  683.     }
  684.     mkangles();
  685.     mknorms();
  686. }
  687.  
  688.  
  689. void mkangles(void)
  690. {
  691.     register int x, maxx, frame;
  692.  
  693.     maxx = PGSEGS -1;
  694.     for (frame = 0; frame < OPENFRAMES; frame++) {
  695.     for (x = 0; x < maxx; x++) {
  696.         ropenangle[frame][x] = 
  697.         getangle(ropenpg[frame][x][0],ropenpg[frame][x+1][0]);
  698.  
  699.         lopenangle[frame][x] =
  700.         getangle(lopenpg[frame][x+1][0],lopenpg[frame][x][0]);
  701.     }
  702.     }
  703.  
  704.     for (frame = 0; frame < TURNFRAMES; frame++) {
  705.     for (x = 0; x < maxx; x++) {
  706.         frontrturnangle[frame][x] = 
  707.         getangle(rtolpglst[frame][x][0],rtolpglst[frame][x+1][0]);
  708.         backrturnangle[frame][x] =
  709.         getangle(rtolpglst[frame][x+1][0],rtolpglst[frame][x][0]);
  710.  
  711.         backlturnangle[frame][x] = 
  712.         getangle(ltorpglst[frame][x+1][0],ltorpglst[frame][x][0]);
  713.         frontlturnangle[frame][x] =
  714.         getangle(ltorpglst[frame][x][0],ltorpglst[frame][x+1][0]);
  715.     }
  716.     }
  717. }
  718.  
  719.  
  720. static float getangle(register float vtx1[3], register float vtx2[3])
  721. {
  722.     register float dx, dz, angle;
  723.  
  724.     dx = vtx2[0] - vtx1[0];
  725.     dz = vtx2[2] - vtx1[2];
  726.  
  727.     if (dz == 0 && dx ==0) {
  728.     fprintf(stderr,"error in angle calculation\n");
  729.     return(0);
  730.     }
  731.  
  732.     angle = atan2f(-dz,dx);
  733.     angle *= 360.0 / (2.0 * M_PI);
  734.  
  735.     return(angle);
  736. }
  737.  
  738.  
  739. void mknorms()
  740. {
  741.     register int frame, x, y;
  742.  
  743.     for (frame = 0; frame < TURNFRAMES; frame++) {
  744.     for (x = 0; x < PGSEGS -1; x++) {
  745.         for (y = 0; y < VPGSEGS -1; y++) {
  746.         normdot(rtolpglst[frame][x][y],rtolpglst[frame][x+1][y],
  747.          rtolpglst[frame][x+1][y+1],rtolnorm[frame][x][y],
  748.          COUNTER_CLOCKWISE);
  749.  
  750.         normdot(ltorpglst[frame][x+1][y],ltorpglst[frame][x][y],
  751.          ltorpglst[frame][x][y+1],ltornorm[frame][x][y],
  752.          COUNTER_CLOCKWISE);
  753.             
  754.  
  755.         }
  756.     }
  757.     }
  758. }
  759.  
  760.  
  761. /* assume positive normal for COUNTER_CLOCKWISE position */
  762. normdot(v0, v1, v2, norm, direction)
  763. float v0[3], v1[3], v2[3], norm[3];
  764. int direction;
  765. {
  766.     float x0, x1, y0, y1, z0, z1;
  767.     float rad;
  768.  
  769.     x0 = v0[0] - v1[0];
  770.     y0 = v0[1] - v1[1];
  771.     z0 = v0[2] - v1[2];
  772.  
  773.     x1 = v2[0] - v1[0];
  774.     y1 = v2[1] - v1[1];
  775.     z1 = v2[2] - v1[2];
  776.  
  777.     norm[0] = y0 * z1 - z0 * y1;
  778.     norm[1] = -(x0 * z1 - z0 * x1);
  779.     norm[2] = x0 * y1 - y0 * x1;
  780.  
  781.     rad = sqrt (norm[0] * norm[0] + norm[1] * norm[1] + norm[2] * norm[2]);
  782.     /* change these to positive for clockwise normal */
  783.     norm[0] = (float)direction * norm[0]/rad;
  784.     norm[1] = (float)direction * norm[1]/rad;
  785.     norm[2] = (float)direction * norm[2]/rad;
  786. }
  787.  
  788.  
  789.  
  790. /*******************************************************
  791. /* MOTION  STUFF
  792. /******************************************************/
  793.  
  794. /* this routine increments through the keyframes to draw the book opening.
  795.    NOTE:  it does not draw the last frame of the opened book - pgn = 0 */
  796. void openbook(register int rotateflag)
  797. {
  798.     register int pgn;
  799.  
  800.     /* to draw the fully open book change pgn > 0 to pgn >= 0 */
  801.     /* for (pgn = OPENFRAMES -1; pgn >= 0; pgn--) { /* draw fully open book  */
  802.     for (pgn = OPENFRAMES -1; pgn > 0; pgn--) {  /* draw once */
  803.  
  804.     cpack(0);
  805.     clear();
  806. /*
  807.     zclear();
  808. */
  809.  
  810.     /* probably want to draw the background here */
  811.  
  812.     if (rotateflag) {
  813.         rotate(ROTINC,'x');
  814.         rotate(ROTINC,'y');
  815.     }
  816.  
  817.         pushmatrix();
  818.         rot(-25.0, 'x');
  819.         translate(0.0, 1.0, 0.0);
  820.     drawopenframe(pgn);
  821.         popmatrix();
  822.     
  823.     swapbuffers();
  824. /*
  825.  if (pgn == OPENFRAMES -1)
  826.  sginap(100);
  827. */
  828.     }
  829. }
  830.  
  831. /* This is the same as drawopenframe() except it does a clear before and a
  832.    swapbuffers() after.  Use this if you want to only draw the book open */
  833. drawopenbook(register int rotateflag)
  834. {
  835.     cpack(0);
  836.     clear();
  837.  
  838.     if (rotateflag) {
  839.     zclear();
  840.     }
  841.  
  842.     drawopenframe(0);
  843.     swapbuffers();
  844. }
  845.  
  846.  
  847. #if DRAWSOLIDPAGES
  848. static void drawsolidpages()
  849. {
  850.     int x, y;
  851.     float carray[3];
  852.    
  853.     y = VPGSEGS - 1;
  854.     bgnpolygon();
  855.     for (x = 0; x < PGSEGS; x++) {
  856.         mkcolor(carray,pgcolor,ropenpg[0][x][y]);
  857.         c3f(carray);
  858.         v3f(ropenpg[0][x][y]);
  859.     }
  860.     for (x = PGSEGS - 1; x >= 0; x--) {
  861.         mkcolor(carray,pgcolor,ropenpg[0][x][0]);
  862.         c3f(carray);
  863.         v3f(ropenpg[0][x][0]);
  864.     }
  865.     endpolygon();
  866.     bgnpolygon();
  867.     for (x = 0; x < PGSEGS; x++) {
  868.         mkcolor(carray,pgcolor,lopenpg[0][x][y]);
  869.         c3f(carray);
  870.         v3f(lopenpg[0][x][y]);
  871.     }
  872.     for (x = PGSEGS - 1; x >= 0; x--) {
  873.         mkcolor(carray,pgcolor,lopenpg[0][x][0]);
  874.         c3f(carray);
  875.         v3f(lopenpg[0][x][0]);
  876.     }
  877.     endpolygon();
  878. }    
  879. #endif    
  880.     
  881.  
  882. void pickdrawopenframe(register int pgn)
  883. {
  884.     pickdrawedges(ropenpg[pgn],lopenpg[pgn],ropenbasepg[pgn],lopenbasepg[pgn]);
  885.     if (pgn != (OPENFRAMES - 1)) {  /* don't draw pages when book is closed */
  886.         if (leftpage != NULL && closeup <= 0)
  887.            pickdrawicons(leftpage, BACK, lopenpg[pgn], lopenangle[pgn]);
  888.         if (rightpage != NULL && closeup >= 0)
  889.            pickdrawicons(rightpage, FRONT, ropenpg[pgn], ropenangle[pgn]);
  890.     }
  891. }
  892.  
  893. /* this routing draws a keyframe (frame #pgn) of the book opening */
  894. void drawopenframe(register int pgn)
  895. {
  896.    float tmp;
  897.  
  898.     tmp = color_mult;
  899.     color_mult = 1.0;
  900.     drawopencover(ropencover[pgn],lopencover[pgn]);
  901.     fillopenpages(ropenpg[pgn],lopenpg[pgn],ropenbasepg[pgn],lopenbasepg[pgn]);
  902.  
  903. #if DRAWSOLIDPAGES
  904.     if (pgn == 0 && !isdoublebuffer())
  905.     drawsolidpages();
  906. #endif
  907.  
  908.     if (pgn != (OPENFRAMES - 1)) {  /* don't draw pages when book is closed */
  909.     drawopenpages(ropenpg[pgn],lopenpg[pgn]);
  910.         if (leftpage != NULL && closeup <= 0)
  911.            drawicons(leftpage, BACK, lopenpg[pgn], lopenangle[pgn]);
  912.         if (rightpage != NULL && closeup >= 0)
  913.            drawicons(rightpage, FRONT, ropenpg[pgn], ropenangle[pgn]);
  914. /*
  915. drawicons_dave(lopenpg[pgn],ropenpg[pgn],lopenangle[pgn],ropenangle[pgn]);
  916. */
  917.     }
  918.     if (!OPENBOOK)
  919.        color_mult = tmp;
  920. }
  921.  
  922.  
  923. /* Draw the cover and the binding of the book.  This routine can be sped up
  924.    considerably by pre-calculating color arrays for the right and left cover
  925.    and the binding */
  926. static void drawopencover(register float rcover[COVERSEGS][2][THREED], 
  927.     register float lcover[PGSEGS][2][THREED])
  928. {
  929.     register float carray[3];
  930.  
  931.     /* draw the right cover */
  932.     bgnpolygon();
  933.     mkcolor(carray,covercolor,rcover[0][0]);
  934.     c3f(carray);
  935.     v3f(rcover[0][0]);
  936.     mkcolor(carray,covercolor,rcover[1][0]);
  937.     c3f(carray);
  938.     v3f(rcover[1][0]);
  939.     mkcolor(carray,covercolor,rcover[1][1]);
  940.     c3f(carray);
  941.     v3f(rcover[1][1]);
  942.     mkcolor(carray,covercolor,rcover[0][1]);
  943.     c3f(carray);
  944.     v3f(rcover[0][1]);
  945.     endpolygon();
  946.  
  947.     /* draw the left cover */        
  948.     bgnpolygon();
  949.     mkcolor(carray,covercolor,lcover[0][0]);
  950.     c3f(carray);
  951.     v3f(lcover[0][0]);
  952.     mkcolor(carray,covercolor,lcover[1][0]);
  953.     c3f(carray);
  954.     v3f(lcover[1][0]);
  955.     mkcolor(carray,covercolor,lcover[1][1]);
  956.     c3f(carray);
  957.     v3f(lcover[1][1]);
  958.     mkcolor(carray,covercolor,lcover[0][1]);
  959.     c3f(carray);
  960.     v3f(lcover[0][1]);
  961.     endpolygon();
  962.  
  963.     drawbinding();
  964. }
  965.  
  966. void darken(register float carray[3])
  967. {
  968.    float rdiff, bdiff, gdiff;
  969.  
  970.    rdiff = carray[0] * .25;
  971.    bdiff = carray[1] * .25;
  972.    gdiff = carray[2] * .25;
  973.   
  974.    carray[0] = carray[0] - rdiff;
  975.    carray[1] = carray[1] - bdiff;
  976.    carray[2] = carray[2] - gdiff;
  977.  
  978.    if (carray[0] < 0.0)
  979.       carray[0] = 0.0;
  980.    if (carray[1] < 0.0)
  981.       carray[1] = 0.0;
  982.    if (carray[2] < 0.0)
  983.       carray[2] = 0.0;
  984. }
  985.  
  986. void lighten(register float carray[3])
  987. {
  988.    float rdiff, bdiff, gdiff;
  989.  
  990.    rdiff = 1.0 - carray[0];
  991.    bdiff = 1.0 - carray[1];
  992.    gdiff = 1.0 - carray[2];
  993.    
  994.    carray[0] = carray[0] + rdiff * .25;
  995.    carray[1] = carray[1] + bdiff * .25;
  996.    carray[2] = carray[2] + gdiff * .25;
  997.  
  998.    if (carray[0] > 1.0)
  999.       carray[0] = 1.0;
  1000.    if (carray[1] > 1.0)
  1001.       carray[1] = 1.0;
  1002.    if (carray[2] > 1.0)
  1003.       carray[2] = 1.0;
  1004. }
  1005.  
  1006. void outlinebinding()
  1007. {
  1008.    bgnline();
  1009.       v3f(sbinding[0][0]);
  1010.       v3f(sbinding[0][1]);
  1011.       v3f(sbinding[BINDINGSEGS - 1][1]);
  1012.       v3f(sbinding[BINDINGSEGS - 1][0]);
  1013.       v3f(sbinding[0][0]);
  1014.    endline();
  1015. }
  1016.  
  1017. void drawbinding()
  1018. {
  1019.     register int x;
  1020.     register float carray[3];
  1021.  
  1022.     /* draw the binding */        
  1023.     for (x = 0; x < (BINDINGSEGS - 1); x++) {
  1024.     bgnpolygon();
  1025.         mkcolor(carray,covercolor,sbinding[x][0]);
  1026.             if (x == 2)
  1027.                lighten(carray);
  1028.             else if (x == 0)
  1029.                darken(carray);
  1030.         c3f(carray);
  1031.         v3f(sbinding[x][0]);
  1032.         mkcolor(carray,covercolor,sbinding[x+1][0]);
  1033.             if (x == 2)
  1034.                lighten(carray);
  1035.             else if (x == 0)
  1036.                darken(carray);
  1037.         c3f(carray);
  1038.         v3f(sbinding[x+1][0]);
  1039.         mkcolor(carray,covercolor,sbinding[x+1][1]);
  1040.             if (x == 2)
  1041.                lighten(carray);
  1042.             else if (x == 0)
  1043.                darken(carray);
  1044.         c3f(carray);
  1045.         v3f(sbinding[x+1][1]);
  1046.         mkcolor(carray,covercolor,sbinding[x][1]);
  1047.             if (x == 2)
  1048.                lighten(carray);
  1049.             else if (x == 0)
  1050.                darken(carray);
  1051.         c3f(carray);
  1052.         v3f(sbinding[x][1]);
  1053.     endpolygon();
  1054.     }    
  1055. }
  1056.  
  1057. void outlineedge(register float pg[PGSEGS][VPGSEGS][THREED],
  1058.            register float base[3][2][THREED])
  1059. {
  1060.    pushmatrix();
  1061.    rot(-25.0, 'x');
  1062.    translate(0.0, 1.0, 0.0);
  1063.    bgnline();
  1064.    v3f(base[2][0]);
  1065.    v3f(base[2][1]);
  1066.    v3f(pg[PGSEGS -1][VPGSEGS - 1]);
  1067.    v3f(pg[PGSEGS -1][0]);
  1068.    v3f(base[2][0]);
  1069.    endline();
  1070.    popmatrix();
  1071. }
  1072.  
  1073. void outlineleftedge()
  1074. {
  1075.    dooverlayview();
  1076.    color(PUP_COLOR);
  1077.    outlineedge( lopenpg[0],lopenbasepg[0]);
  1078.    dobookview();
  1079. }
  1080.  
  1081. void outlinerightedge()
  1082. {
  1083.    dooverlayview();
  1084.    color(PUP_COLOR);
  1085.    outlineedge( ropenpg[0],ropenbasepg[0]);
  1086.    dobookview();
  1087. }
  1088.  
  1089. void pickdrawedges(register float ropg[PGSEGS][VPGSEGS][THREED],
  1090.     register float lopg[PGSEGS][VPGSEGS][THREED],
  1091.     register float robase[3][2][THREED], register float lobase[3][2][THREED])
  1092. {
  1093.    /* leftside */
  1094.    if (leftpage != NULL)
  1095.       {
  1096.       loadname(80);
  1097.       bgnpolygon();
  1098.          v3f(lobase[2][0]);
  1099.          v3f(lobase[2][1]);
  1100.          v3f(lopg[PGSEGS -1][VPGSEGS - 1]);
  1101.          v3f(lopg[PGSEGS -1][0]);
  1102.       endpolygon();
  1103.       }
  1104.    /* rightside */
  1105.    if (rightpage != NULL)
  1106.       {
  1107.       loadname(81);
  1108.       bgnpolygon();
  1109.          v3f(robase[2][0]);
  1110.          v3f(robase[2][1]);
  1111.          v3f(ropg[PGSEGS -1][VPGSEGS - 1]);
  1112.          v3f(ropg[PGSEGS -1][0]);
  1113.       endpolygon();
  1114.       }
  1115. }
  1116.  
  1117. /* This routine draws the page edges between the cover and the inside right and
  1118.    left pages of the opening book.  The openbasepage is the page flattened out
  1119.    on the cover.  This routine can be sped up considerably by pre-calculating
  1120.    color arrays for the right and left page edges and the right and left
  1121.    basepages. */
  1122. static void fillopenpages(register float ropg[PGSEGS][VPGSEGS][THREED], 
  1123.     register float lopg[PGSEGS][VPGSEGS][THREED], 
  1124.     register float robase[3][2][THREED], register float lobase[3][2][THREED])
  1125. {
  1126.     register int x;
  1127.     register float carray[3];
  1128.  
  1129.     /* draw the back right page edges */
  1130.     bgnpolygon();
  1131.  
  1132.     /* trace along the page edge */
  1133.     for (x = 0; x < PGSEGS; x++) {
  1134.         mkcolor(carray,pgedgecolor,ropg[x][VPGSEGS - 1]);
  1135.         c3f(carray);
  1136.         v3f(ropg[x][VPGSEGS - 1]);
  1137.     }
  1138.  
  1139.     /* trace along the basepage */
  1140.     mkcolor(carray,pgedgecolor,robase[2][1]);
  1141.     c3f(carray);
  1142.     v3f(robase[2][1]);
  1143.     mkcolor(carray,pgedgecolor,robase[1][1]);
  1144.     c3f(carray);
  1145.     v3f(robase[1][1]);
  1146.     mkcolor(carray,pgedgecolor,robase[0][1]);
  1147.     c3f(carray);
  1148.     v3f(robase[0][1]);
  1149.     endpolygon();
  1150.  
  1151.     /* draw the right side page edges */
  1152.     bgnpolygon();
  1153.     mkcolor(carray,pgedgecolor,robase[2][0]);
  1154.     c3f(carray);
  1155.     v3f(robase[2][0]);
  1156.     mkcolor(carray,pgedgecolor,robase[2][1]);
  1157.     c3f(carray);
  1158.     v3f(robase[2][1]);
  1159.     mkcolor(carray,pgedgecolor,ropg[PGSEGS -1][VPGSEGS - 1]);
  1160.     c3f(carray);
  1161.     v3f(ropg[PGSEGS -1][VPGSEGS - 1]);
  1162.     mkcolor(carray,pgedgecolor,ropg[PGSEGS -1][0]);
  1163.     c3f(carray);
  1164.     v3f(ropg[PGSEGS -1][0]);
  1165.     endpolygon();
  1166.  
  1167.     /* draw the left side of the right pages (above the binding) ??? */
  1168.  
  1169.     /* fraw the right front page edges */
  1170.     bgnpolygon();
  1171.  
  1172.     /* trace along the page edge */
  1173.     for (x = 0; x < PGSEGS; x++) {
  1174.         mkcolor(carray,pgedgecolor,ropg[x][0]);
  1175.         c3f(carray);
  1176.         v3f(ropg[x][0]);
  1177.     }
  1178.  
  1179.     /* trace along the basepage */
  1180.     mkcolor(carray,pgedgecolor,robase[2][0]);
  1181.     c3f(carray);
  1182.     v3f(robase[2][0]);
  1183.     mkcolor(carray,pgedgecolor,robase[1][0]);
  1184.     c3f(carray);
  1185.     v3f(robase[1][0]);
  1186.     mkcolor(carray,pgedgecolor,robase[0][0]);
  1187.     c3f(carray);
  1188.     v3f(robase[0][0]);
  1189.     endpolygon();
  1190.  
  1191.     /* draw the back left page edges */
  1192.     bgnpolygon();
  1193.  
  1194.     /* trace along the page edge */
  1195.     for (x = 0; x < PGSEGS; x++) {
  1196.         mkcolor(carray,pgedgecolor,lopg[x][VPGSEGS - 1]);
  1197.         c3f(carray);
  1198.         v3f(lopg[x][VPGSEGS - 1]);
  1199.     }
  1200.  
  1201.     /* trace along the basepage */
  1202.     mkcolor(carray,pgedgecolor,lobase[2][1]);
  1203.     c3f(carray);
  1204.     v3f(lobase[2][1]);
  1205.     mkcolor(carray,pgedgecolor,lobase[1][1]);
  1206.     c3f(carray);
  1207.     v3f(lobase[1][1]);
  1208.     mkcolor(carray,pgedgecolor,lobase[0][1]);
  1209.     c3f(carray);
  1210.     v3f(lobase[0][1]);
  1211.     endpolygon();
  1212.  
  1213.     /* draw the left side page edges */
  1214.     bgnpolygon();
  1215.     mkcolor(carray,pgedgecolor,lobase[2][0]);
  1216.     c3f(carray);
  1217.     v3f(lobase[2][0]);
  1218.     mkcolor(carray,pgedgecolor,lobase[2][1]);
  1219.     c3f(carray);
  1220.     v3f(lobase[2][1]);
  1221.     mkcolor(carray,pgedgecolor,lopg[PGSEGS -1][VPGSEGS - 1]);
  1222.     c3f(carray);
  1223.     v3f(lopg[PGSEGS -1][VPGSEGS - 1]);
  1224.     mkcolor(carray,pgedgecolor,lopg[PGSEGS -1][0]);
  1225.     c3f(carray);
  1226.     v3f(lopg[PGSEGS -1][0]);
  1227.     endpolygon();
  1228.  
  1229.     /* Could draw the right side of the left pages (above the binding), but I
  1230.        don't think we really need this */
  1231.  
  1232.     /* fraw the left front page edges */
  1233.     bgnpolygon();
  1234.  
  1235.     /* trace along the page edge */
  1236.     for (x = 0; x < PGSEGS; x++) {
  1237.         mkcolor(carray,pgedgecolor,lopg[x][0]);
  1238.         c3f(carray);
  1239.         v3f(lopg[x][0]);
  1240.     }
  1241.  
  1242.     /* trace along the basepage */
  1243.     mkcolor(carray,pgedgecolor,lobase[2][0]);
  1244.     c3f(carray);
  1245.     v3f(lobase[2][0]);
  1246.     mkcolor(carray,pgedgecolor,lobase[1][0]);
  1247.     c3f(carray);
  1248.     v3f(lobase[1][0]);
  1249.     mkcolor(carray,pgedgecolor,lobase[0][0]);
  1250.     c3f(carray);
  1251.     v3f(lobase[0][0]);
  1252.     endpolygon();
  1253. }
  1254.  
  1255. void findleftpagesquare(int *x_ndx, int *y_ndx)
  1256. {
  1257.     register int x,y;
  1258.     register int maxsq = PGSEGS - 1;
  1259.     register int maxvsq = VPGSEGS - 1;
  1260.     int name;
  1261.     short picbuf[PICBUFSIZ];
  1262.     int hits, i, j, c, num;
  1263.     int picked;
  1264.  
  1265.     dobookview();
  1266.     name = 0;
  1267.     picked = -1;
  1268.     pick(picbuf, PICBUFSIZ);
  1269.     dobookview();
  1270.     initnames();
  1271.     pushmatrix();
  1272.     rot(-25.0, 'x');
  1273.     translate(0.0, 1.0, 0.0);
  1274.     /* draw the sections that make up the left page */
  1275.     for (x = 0; x < maxsq; x++) {
  1276.         for (y = 0; y < maxvsq; y++) {
  1277.             loadname(name);
  1278.             /* will never have to draw icon on 2 sides with this routine */
  1279.             drawsquare(lopenpg[0],x,y);
  1280.             name++;
  1281.         }
  1282.     }
  1283.     popmatrix();
  1284.     hits = endpick(picbuf);
  1285.     picked = get_picked(picbuf, hits);
  1286.     dobookview();
  1287.     if (picked >= 0 && picked < 100)
  1288.        {
  1289.        *x_ndx = picked / (maxsq-1);
  1290.        *y_ndx = picked - (*x_ndx*(maxsq-1));
  1291.        }
  1292.     else
  1293.        {
  1294.        *x_ndx = -1;
  1295.        *y_ndx = -1;
  1296.        }
  1297. }
  1298.  
  1299. void findrightpagesquare( int *x_ndx, int *y_ndx)
  1300. {
  1301.     register int x,y;
  1302.     register int maxsq = PGSEGS - 1;
  1303.     register int maxvsq = VPGSEGS - 1;
  1304.     int name;
  1305.     short picbuf[PICBUFSIZ];
  1306.     int hits, i, j, c, num;
  1307.     int picked;
  1308.  
  1309.     name = 0;
  1310.     dobookview();
  1311.     picked = -1;
  1312.     pick(picbuf, PICBUFSIZ);
  1313.     dobookview();
  1314.     initnames();
  1315.     pushmatrix();
  1316.     rot(-25.0, 'x');
  1317.     translate(0.0, 1.0, 0.0);
  1318.     /* draw the sections that make up the left page */
  1319.     for (x = 0; x < maxsq; x++) {
  1320.         for (y = 0; y < maxvsq; y++) {
  1321.             loadname(name);
  1322.             /* will never have to draw icon on 2 sides with this routine */
  1323.             drawsquare(ropenpg[0],x,y);
  1324.             name++;
  1325.         }
  1326.     }
  1327.     popmatrix();
  1328.     hits = endpick(picbuf);
  1329.     picked = get_picked(picbuf, hits);
  1330.     dobookview();
  1331.     if (picked >= 0 && picked < 100)
  1332.        {
  1333.        *x_ndx = picked / (maxsq-1);
  1334.        *y_ndx = picked - (*x_ndx*(maxsq-1));
  1335.        }
  1336.     else
  1337.        {
  1338.        *x_ndx = -1;
  1339.        *y_ndx = -1;
  1340.        }
  1341. }
  1342.  
  1343.  
  1344. /* draw the left and right opening pages.  This routine could be speeded up
  1345.    considerably by pre-calculating color arrays for the left and right page
  1346.    vertices */
  1347.  
  1348. static void drawopenpages(register float rpg[PGSEGS][VPGSEGS][THREED], 
  1349.     register float lpg[PGSEGS][VPGSEGS][THREED])
  1350. {
  1351.     register int x,y;
  1352.     register int maxsq = PGSEGS - 1;
  1353.     register int maxvsq = VPGSEGS - 1;
  1354.  
  1355.     /* draw the sections that make up the right page */
  1356.     for (x = 0; x < maxsq; x++) {
  1357.     for (y = 0; y < maxvsq; y++) {
  1358.         /* will never have to draw icon on 2 sides with this routine */
  1359.         drawsquare(rpg,x,y);
  1360.     }
  1361.     }
  1362.  
  1363.     /* draw the sections that make up the left page */
  1364.     for (x = 0; x < maxsq; x++) {
  1365.     for (y = 0; y < maxvsq; y++) {
  1366.         /* will never have to draw icon on 2 sides with this routine */
  1367.         drawsquare(lpg,x,y);
  1368.     }
  1369.     }
  1370.  
  1371.     drawcrack();
  1372. }
  1373.  
  1374. void turnpage(int side)
  1375. {
  1376.    dobookview();
  1377.    mkdoublebuffer();
  1378.    pushmatrix();
  1379.    rot(-25.0, 'x');
  1380.    translate(0.0, 1.0, 0.0);
  1381.    if (side == 0) /* left */
  1382.       {
  1383.       middlepage = leftpage;
  1384.       leftpage = leftpage->prevpage;
  1385.       ltor_turn();
  1386.       rightpage = middlepage;
  1387.       }
  1388.    else if (side == 1)   /* right */
  1389.       {
  1390.       middlepage = rightpage;
  1391.       rightpage = rightpage->nextpage;
  1392.       rtol_turn();
  1393.       leftpage = middlepage;
  1394.       }
  1395.    middlepage = NULL;
  1396.    mksinglebuffer();
  1397.    c3s(morecolors[10]);
  1398.    clear();
  1399.    drawopenframe(0);
  1400.    popmatrix();
  1401.    swapbuffers();
  1402. }
  1403.  
  1404. void rtol_turn()
  1405. {
  1406.     register int frame, x, y;
  1407.     register int maxframe = TURNFRAMES -1;
  1408.     register int maxx = PGSEGS - 1;
  1409.     register int maxy = VPGSEGS - 1;
  1410.     float carray[3];
  1411.     struct icntmpltstruct * fronticon[PGSEGS-1][VPGSEGS-1];
  1412.     struct icntmpltstruct * backicon[PGSEGS-1][VPGSEGS-1];
  1413.     struct iconstruct *tmpicon;
  1414.     float transname;
  1415.     int count;
  1416.  
  1417.     for (x = 0; x < maxx; x++)
  1418.        {
  1419.        for (y = 0; y < maxy; y++)
  1420.           {
  1421.           fronticon[x][y] = NULL;
  1422.           backicon[x][y] = NULL;
  1423.           }
  1424.        }
  1425.     tmpicon = middlepage->fronticons;
  1426.     count = 0;
  1427.     while (tmpicon != NULL && count < ICONLIMIT)
  1428.        {
  1429.        if (!Hide || tmpicon->ok)
  1430.           {
  1431.           fronticon[tmpicon->xposition_ndx][tmpicon->yposition_ndx] = tmpicon->iconptr;
  1432.           count++;
  1433.           }
  1434.        tmpicon = tmpicon->nexticon;
  1435.        }
  1436.     tmpicon = middlepage->backicons;
  1437.     count = 0;
  1438.     while (tmpicon != NULL && count < ICONLIMIT)
  1439.        {
  1440.        if (!Hide || tmpicon->ok)
  1441.           {
  1442.           backicon[tmpicon->xposition_ndx][tmpicon->yposition_ndx] = tmpicon->iconptr;
  1443.           count++;
  1444.           }
  1445.        tmpicon = tmpicon->nexticon;
  1446.        }
  1447.     for (frame = 1; frame < maxframe; frame++) {
  1448.     cpack(0);
  1449.     clear();
  1450.      zclear();
  1451.  
  1452.     drawopenframe(0);
  1453.  
  1454.     /* draw the turning page */
  1455.     for (x = 0; x < maxx; x++) {
  1456.         for (y = 0; y < maxy; y++) {
  1457.                 transname = -.15;
  1458.         drawsquare(rtolpglst[frame],x,y);
  1459.         if (rtolnorm[frame][x][y][2] > 0) { /* if front pointing up */
  1460.         if (fronticon[x][y] != NULL)
  1461.                    {
  1462.                    pushmatrix();
  1463.                    translate( rtolpglst[frame][x][y][0],
  1464.                        rtolpglst[frame][x][y][1]+.4, rtolpglst[frame][x][y][2]);
  1465.                    rotate( (int)(frontrturnangle[frame][x] * 10 + 0.5), 'y');
  1466.                    if (fronticon[x][y]->poly != NULL)
  1467.                          drawicon_geom(0, fronticon[x][y]);
  1468.                    else if (fronticon[x][y]->tex_image != NULL)
  1469.                          drawicon_img(0,fronticon[x][y]);
  1470.                    else
  1471.                       transname = 1.125;
  1472.                    pushmatrix();
  1473.                    translate(0.0, transname, 0.0);
  1474.                    draw_demoname(fronticon[x][y]);
  1475.                    popmatrix();
  1476.                    popmatrix();
  1477.                    }
  1478.         } else  {/* front must point down */
  1479.            if (backicon[x][y] != NULL) 
  1480.                    {
  1481.                    pushmatrix();
  1482.                    translate( rtolpglst[frame][x+1][y][0],
  1483.                        rtolpglst[frame][x+1][y][1]+.4, rtolpglst[frame][x+1][y][2]);
  1484.                    rotate( (int)(backrturnangle[frame][x] * 10 + 0.5), 'y');
  1485.                    if (backicon[x][y]->poly != NULL)
  1486.                          drawicon_geom(0, backicon[x][y]);
  1487.                    else if (backicon[x][y]->tex_image != NULL)
  1488.                          drawicon_img(0,backicon[x][y]);
  1489.                    else
  1490.                       transname = 1.125;
  1491.                    pushmatrix();
  1492.                    translate(0.0, transname, 0.0);
  1493.                    draw_demoname(backicon[x][y]);
  1494.                    popmatrix();
  1495.                    popmatrix();
  1496.                    }
  1497.         }
  1498.         }
  1499.         if (x == 0)
  1500.         drawcrack();
  1501.     }
  1502.  
  1503.     /* outline the page */
  1504.     bgnline();
  1505.     for (x = 0; x < PGSEGS; x++) {
  1506.         mkcolor(carray,pgedgecolor,rtolpglst[frame][x][0]);
  1507.         c3f(carray);
  1508.         v3f(rtolpglst[frame][x][0]);
  1509.     }
  1510.     mkcolor(carray,pgedgecolor,rtolpglst[frame][PGSEGS-1][VPGSEGS-1]);
  1511.     c3f(carray);
  1512.     v3f(rtolpglst[frame][PGSEGS-1][VPGSEGS-1]);
  1513.     endline();
  1514.       swapbuffers();
  1515.     }
  1516. }
  1517.  
  1518.  
  1519. void ltor_turn()
  1520. {
  1521.     register int frame, x, y;
  1522.     register int maxframe = TURNFRAMES -1;
  1523.     register int maxx = PGSEGS - 1;
  1524.     register int maxy = VPGSEGS - 1;
  1525.     float carray[3];
  1526.     struct icntmpltstruct * fronticon[PGSEGS-1][VPGSEGS-1];
  1527.     struct icntmpltstruct * backicon[PGSEGS-1][VPGSEGS-1];
  1528.     struct iconstruct *tmpicon;
  1529.     float transname;
  1530.     int count;
  1531.  
  1532.     for (x = 0; x < maxx; x++)
  1533.        {
  1534.        for (y = 0; y < maxy; y++)
  1535.           {
  1536.           fronticon[x][y] = NULL;
  1537.           backicon[x][y] = NULL;
  1538.           }
  1539.        }
  1540.     tmpicon = middlepage->fronticons;
  1541.     count = 0;
  1542.     while (tmpicon != NULL && count < ICONLIMIT)
  1543.        {
  1544.        if (!Hide || tmpicon->ok)
  1545.           {
  1546.           fronticon[tmpicon->xposition_ndx][tmpicon->yposition_ndx] = tmpicon->iconptr;
  1547.           count++;
  1548.           }
  1549.        tmpicon = tmpicon->nexticon;
  1550.        }
  1551.     tmpicon = middlepage->backicons;
  1552.     count = 0;
  1553.     while (tmpicon != NULL && count < ICONLIMIT)
  1554.        {
  1555.        if (!Hide || tmpicon->ok)
  1556.           {
  1557.           backicon[tmpicon->xposition_ndx][tmpicon->yposition_ndx] = tmpicon->iconptr;
  1558.           count++;
  1559.           }
  1560.        tmpicon = tmpicon->nexticon;
  1561.        }
  1562.  
  1563.     for (frame = 1; frame < maxframe; frame++) {
  1564.     cpack(0);
  1565.     clear();
  1566.     zclear();
  1567.  
  1568.     drawopenframe(0);
  1569.  
  1570.     /* draw the turning page */
  1571.     for (x = 0; x < maxx; x++) {
  1572.         for (y = 0; y < maxy; y++) {
  1573.                 transname = -.15;
  1574.         drawsquare(ltorpglst[frame],x,y);
  1575.         if (ltornorm[frame][x][y][2] > 0) {  /* if back pointing up */
  1576.            if (backicon[x][y] != NULL) 
  1577.                    {
  1578.                    pushmatrix();
  1579.                    translate( ltorpglst[frame][x+1][y][0],
  1580.                        ltorpglst[frame][x+1][y][1]+.4, ltorpglst[frame][x+1][y][2]);
  1581.                    rotate((int)(backlturnangle[frame][x] * 10 + 0.5), 'y');
  1582.                    if (backicon[x][y]->poly != NULL)
  1583.                          drawicon_geom(0, backicon[x][y]);
  1584.                    else if (backicon[x][y]->tex_image != NULL)
  1585.                          drawicon_img(0,backicon[x][y]);
  1586.                    else
  1587.                        transname = 1.125;
  1588.                    pushmatrix();
  1589.                    translate(0.0, transname, 0.0);
  1590.                    draw_demoname(backicon[x][y]);
  1591.                    popmatrix();
  1592.                    popmatrix();
  1593.                    }
  1594.         } else  {/* front must point up */
  1595.         if (fronticon[x][y] != NULL)
  1596.                    {
  1597.                    pushmatrix();
  1598.                    translate( ltorpglst[frame][x][y][0],
  1599.                        ltorpglst[frame][x][y][1]+.4, ltorpglst[frame][x][y][2]);
  1600.                    rotate( (int)(frontlturnangle[frame][x] * 10 + 0.5), 'y');
  1601.                    if (fronticon[x][y]->poly != NULL)
  1602.                          drawicon_geom(0, fronticon[x][y]);
  1603.                    else if (fronticon[x][y]->tex_image != NULL)
  1604.                          drawicon_img(0,fronticon[x][y]);
  1605.                    else
  1606.                        transname = 1.125;
  1607.                    pushmatrix();
  1608.                    translate(0.0, transname, 0.0);
  1609.                    draw_demoname(fronticon[x][y]);
  1610.                    popmatrix();
  1611.                    popmatrix();
  1612.                    }
  1613.         }
  1614.         }
  1615.         if (x == 0)
  1616.         drawcrack();
  1617.     }
  1618.  
  1619.     bgnline();
  1620.     for (x = 0; x < PGSEGS; x++) {
  1621.         mkcolor(carray,pgedgecolor,ltorpglst[frame][x][0]);
  1622.         c3f(carray);
  1623.         v3f(ltorpglst[frame][x][0]);
  1624.     }
  1625.     mkcolor(carray,pgedgecolor,ltorpglst[frame][PGSEGS-1][VPGSEGS-1]);
  1626.     c3f(carray);
  1627.     v3f(ltorpglst[frame][PGSEGS-1][VPGSEGS-1]);
  1628.     endline();
  1629.  
  1630.     swapbuffers();
  1631.     }
  1632. }
  1633.  
  1634. /* outline a square section of the page (5x5 squares) */
  1635. static void drawoutlinesquare(register float pgarray[PGSEGS][VPGSEGS][THREED],
  1636.     register int x, register int y)
  1637. {
  1638.    float center[3];
  1639.  
  1640.    center[0] = ( pgarray[x][y][0] + pgarray[x+1][y][0] +
  1641.                     pgarray[x+1][y+1][0] + pgarray[x][y+1][0] ) / 4;
  1642.    center[1] = ( pgarray[x][y][1] + pgarray[x+1][y][1] +
  1643.                     pgarray[x+1][y+1][1] + pgarray[x][y+1][1] ) / 4;
  1644.    center[2] = ( pgarray[x][y][2] + pgarray[x+1][y][2] +
  1645.                     pgarray[x+1][y+1][2] + pgarray[x][y+1][2] ) / 4;
  1646.    pushmatrix();
  1647.    translate(center[0], center[1], center[2]);
  1648.    scale(.9, .9, 1.0);
  1649.    translate(-center[0], -center[1], -center[2]);
  1650.    bgnline();
  1651.       v3f(pgarray[x][y]);
  1652.       v3f(pgarray[x+1][y]);
  1653.       v3f(pgarray[x+1][y+1]);
  1654.       v3f(pgarray[x][y+1]);
  1655.       v3f(pgarray[x][y]);
  1656.     endline();
  1657.    popmatrix();
  1658. }
  1659.  
  1660. /* draw a square section of the page (5x5 squares) */
  1661. static void drawsquare(register float pgarray[PGSEGS][VPGSEGS][THREED], 
  1662.     register int x, register int y)
  1663. {
  1664.     register float carray[3];
  1665.  
  1666.     bgnpolygon();
  1667.         mkcolor(carray,pgcolor,pgarray[x][y]);
  1668.         c3f(carray);
  1669.     v3f(pgarray[x][y]);
  1670.     mkcolor(carray,pgcolor,pgarray[x+1][y]);
  1671.     c3f(carray);
  1672.     v3f(pgarray[x+1][y]);
  1673.     mkcolor(carray,pgcolor,pgarray[x+1][y+1]);
  1674.     c3f(carray);
  1675.     v3f(pgarray[x+1][y+1]);
  1676.         mkcolor(carray,pgcolor,pgarray[x][y+1]);
  1677.         c3f(carray);
  1678.     v3f(pgarray[x][y+1]);
  1679.     endpolygon();
  1680.  
  1681.     /* this is where we can draw the icon for the square section.  There needs
  1682.        to be a flag to determine if we need to draw bothe sides or not */
  1683. }
  1684.  
  1685.  
  1686.  
  1687. /*******************************************************
  1688. /* COLOR STUFF
  1689. /******************************************************/
  1690.  
  1691. void setcovercolor(struct grptmpltstruct *grpptr)
  1692. {
  1693.  
  1694.    covercolor[0] = grpptr->covercolor[0];
  1695.    covercolor[1] = grpptr->covercolor[1];
  1696.    covercolor[2] = grpptr->covercolor[2];
  1697. }
  1698.  
  1699.  
  1700. /* simple color calculation based on distance of light only - Note:  1/14/92
  1701.    this routine called 3496 times to open the book, and 4776 times to turn a
  1702.    page */
  1703. static void mkcolor(register float carray[3], register float srcarray[3], 
  1704.     register float coord[THREED])
  1705. {
  1706.     register float distance;
  1707.     register float dx, dy, dz;
  1708.     static float lightplace[THREED] = {-10,-10,10};
  1709. #if LIGHTCALC
  1710.     static float mindist = 1000.0;
  1711.     static float maxdist = 0.0;
  1712. #endif
  1713.  
  1714.     dx = lightplace[0] - coord[0];
  1715.     dy = lightplace[1] - coord[1];
  1716.     dz = lightplace[2] - coord[2];
  1717.  
  1718.     /* distance - fsqrt(dx*dx + dy*dy + dz*dz); */
  1719.     distance = sqrttable[(int)(dx*dx + dy*dy + dz*dz)];
  1720.  
  1721. #if LIGHTCALC
  1722.     if (mindist > distance) {
  1723.     mindist = distance;
  1724.     printf("mindist=%f\n",mindist);
  1725.     }
  1726.     if (maxdist < distance) {
  1727.     maxdist = distance;
  1728.     printf("maxdist=%f\n",maxdist);
  1729.     }
  1730. #endif
  1731.  
  1732. #if LIGHTCALC
  1733.     carray[0] = carray[1] = carray[2] = 
  1734.     1.0 - ((distance - mindist) / (maxdist - mindist));
  1735. #else
  1736.     /* mindist = 10.34 , maxdist = 31.17 when lightplace = -10,-10,10 */
  1737.     /* mindist = 0.6 , maxdist = 18.4 when lightplace = 0,0,10 */
  1738.     /* mindist = 5.0 , maxdist = 22.9 when lightplace = -5,-5,10 */
  1739.     carray[0] = carray[1] = carray[2] = 1.0 - ((distance - 10.34) / 31.17);
  1740. #endif
  1741.  
  1742.     carray[0] *= srcarray[0] * color_mult;
  1743.     carray[1] *= srcarray[1] * color_mult;
  1744.     carray[2] *= srcarray[2] * color_mult;
  1745.  
  1746. #if LIGHTCALC
  1747.     /* printcolor(carray); */
  1748. #endif
  1749. }
  1750.  
  1751. #if LIGHTCALC
  1752. static void printcolor(float carray[3])
  1753. {
  1754.     printf("%f,%f,%f \n",carray[0],carray[1],carray[2]);
  1755. }
  1756. #endif
  1757.  
  1758.  
  1759. /* draw the crack between the right and left pages */
  1760. static void drawcrack()
  1761. {
  1762.     c3f(crackcolor);
  1763.     bgnline();
  1764.     v3f(crackvtx[0]);
  1765.     v3f(crackvtx[1]);
  1766.     endline();
  1767. }
  1768.  
  1769.  
  1770.  
  1771.  
  1772.  
  1773.            
  1774.  
  1775.